<div class="sect1">
<h2 id="_description">Description</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Formatting strings, either with the <code>%</code> operator or <code>str.format</code> method, requires a valid string and arguments matching this string&#8217;s replacement fields.</p>
</div>
<div class="paragraph">
<p>This also applies to loggers from the <code>logging</code> module. Internally they use <code>%-formatting</code>. The only difference is that they will log an error instead of raising an exception when provided arguments are invalid.</p>
</div>
<div class="paragraph">
<p>Formatted string literals, also called "f-strings", are generally simpler to use, and any syntax mistake will fail at compile time. However it is easy to forget curly braces  and it won&#8217;t raise any error.</p>
</div>
<div class="paragraph">
<p>This rule raises an issue when:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A string formatted with <code>%</code> will not return the expected string because some arguments are not used.</p>
</li>
<li>
<p>A string formatted with <code>str.format</code> will not return the expected string because some arguments are not used.</p>
</li>
<li>
<p>An "f-string" doesn&#8217;t contain any replacement field, which probably means that some curly braces are missing.</p>
</li>
<li>
<p>Loggers will log an error because their message is not formatted properly.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Rule <a data-rspec-id="S2275" class="rspec-auto-link">S2275</a> covers cases where formatting a string will raise an exception.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_noncompliant_code_example">Noncompliant Code Example</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-python" data-lang="python">"Error %(message)s" % {"message": "something failed", "extra": "some dead code"}  # Noncompliant. Remove the unused argument "extra" or add a replacement field.

"Error: User {} has not been able to access []".format("Alice", "MyFile")  # Noncompliant. Remove 1 unexpected argument or add a replacement field.

user = "Alice"
resource = "MyFile"
message = f"Error: User [user] has not been able to access [resource]"  # Noncompliant. Add replacement fields or use a normal string instead of an f-string.

import logging
logging.error("Error: User %s has not been able to access %s", "Alice")  # Noncompliant. Add 1 missing argument.</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_compliant_solution">Compliant Solution</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-python" data-lang="python">"Error %(message)s" % {"message": "something failed"}

"Error: User {} has not been able to access {}".format("Alice", "MyFile")

user = "Alice"
resource = "MyFile"
message = f"Error: User {user} has not been able to access {resource}"

import logging
logging.error("Error: User %s has not been able to access %s", "Alice", "MyFile")</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_see">See</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p><a href="https://docs.python.org/3/library/string.html#format-string-syntax">Python documentation - Format String Syntax</a></p>
</li>
<li>
<p><a href="https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting">Python documentation - printf-style String Formatting</a></p>
</li>
<li>
<p><a href="https://docs.python.org/3/howto/logging.html#loggers">Python documentation - Loggers</a></p>
</li>
<li>
<p><a href="https://docs.python.org/3/howto/logging-cookbook.html#using-particular-formatting-styles-throughout-your-application">Python documentation - Using particular formatting styles throughout your application</a></p>
</li>
<li>
<p><a href="https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals">Python documentation - Formatted string literals</a></p>
</li>
</ul>
</div>
<hr>
</div>
</div>
<div class="sect1">
<h2 id="_implementation_specification">Implementation Specification</h2>
<div class="sectionbody">
<div class="paragraph">
<p>(visible only on this page)</p>
</div>
<div class="sect2">
<h3 id="_message">Message</h3>
<div class="ulist">
<ul>
<li>
<p>Add replacement fields or use a normal string instead of an f-string.</p>
</li>
<li>
<p>Remove this unused argument.</p>
</li>
<li>
<p>Remove X unused positional arguments.</p>
</li>
<li>
<p>Fix this formatted string&#8217;s syntax.</p>
</li>
<li>
<p>Name unnamed replacement field(s).</p>
</li>
<li>
<p>Replace formatting argument(s) with a mapping; Replacement fields are named.</p>
</li>
<li>
<p>Use only positional or named fields, don&#8217;t mix them.</p>
</li>
<li>
<p>Replace this value with a number as "%d" requires.</p>
</li>
<li>
<p>Replace this value with an integer as "%X" requires.</p>
</li>
<li>
<p>Replace this value with an integer as "*" requires.</p>
</li>
<li>
<p>Add X missing argument(s).</p>
</li>
<li>
<p>Remove X unexpected argument(s); format string expects Y arguments.</p>
</li>
<li>
<p>Replace this key; %-format accepts only string keys.</p>
</li>
<li>
<p>Provide a value for field "X".</p>
</li>
<li>
<p>Remove this unused argument or add a replacement field.</p>
</li>
</ul>
</div>
<hr>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_comments_and_links">Comments And Links</h2>
<div class="sectionbody">
<div class="paragraph">
<p>(visible only on this page)</p>
</div>
<div class="sect2">
<h3 id="_is_duplicated_by_s3941">is duplicated by: <a data-rspec-id="S3941" class="rspec-auto-link">S3941</a></h3>

</div>
<div class="sect2">
<h3 id="_is_related_to_s2275">is related to: <a data-rspec-id="S2275" class="rspec-auto-link">S2275</a></h3>

</div>
<div class="sect2">
<h3 id="_on_10_dec_2015_090759_tamas_vajk_wrote">on 10 Dec 2015, 09:07:59 Tamas Vajk wrote:</h3>
<div class="paragraph">
<p>\[~ann.campbell.2] Removed the performance label, as the performance impact is insignificant.</p>
</div>
</div>
<div class="sect2">
<h3 id="_on_10_dec_2015_144405_ann_campbell_wrote">on 10 Dec 2015, 14:44:05 Ann Campbell wrote:</h3>
<div class="paragraph">
<p>I&#8217;ve updated SQALE characteristic to match [~tamas.vajk]</p>
</div>
</div>
</div>
</div>